#ifndef __CHAIN_REGISTER_FACTORY_H__
#define __CHAIN_REGISTER_FACTORY_H__

#include "./includes/register_pack.h"
#include "chain_register.h"
#include "block.h"

class ChainRegisterFactory : public RegisterFactory{
	private:
		unsigned int blockSize;
		unsigned int curr_offset;
	public:
		ChainRegisterFactory(unsigned int blockSize){
			this->blockSize = blockSize;
			this->curr_offset = 0;
		}
		~ChainRegisterFactory(){}
		
		RegisterFactory* duplicate()const{ return (new ChainRegisterFactory(*this)); }
		
		void setCurrentOffset(unsigned int offset){
			this->curr_offset = offset;
		}

		Register* operator()(char* data)const{
			ChainRegister* reg;
			char* reg_part;
			unsigned int size;
			unsigned long int next;
			char* temp = data;
			
			size = this->blockSize-(this->curr_offset+ChainRegister::getPointerSize());

			reg_part = new char[size];
			memcpy(reg_part,temp,size);
			temp += size;
			memcpy((char*)&(next),temp,sizeof(unsigned long int));
			temp += sizeof(unsigned long int);
			
			reg = new ChainRegister(reg_part,size,next);
			delete[] reg_part;
			return reg;
		}
		
		char* operator()(const Register& reg,char* data)const{
			const ChainRegister& cr = dynamic_cast<const ChainRegister&>(reg);
			
			char* temp = data;
			const char* reg_part = cr.peekData();
			unsigned int size = cr.getDataSize();
			unsigned long int next = cr.getNext();
						
			memcpy(temp,reg_part,size);
			temp += size;
			memcpy(temp,(char*)&(next),sizeof(unsigned long int));
			temp += sizeof(unsigned long int);
			return temp;
		}
};


#endif /* __CHAIN_REGISTER_FACTORY_H__ */
